package com.jadesoft.listener;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import com.jadesoft.common.service.PaginationService;
import com.jadesoft.stock.FetionHelper;
import com.jadesoft.stock.entity.FundDaily;
import com.jadesoft.stock.util.Constants;
import com.jadesoft.stock.util.FileUtil;
import com.jadesoft.stock.util.StockUtil;

public class FundTask extends TimerTask {
	private Logger logger = Logger.getLogger(FundTask.class);
	private PaginationService persistence = new PaginationService();
	private Map<String, FundDaily> fundDailyMap = new HashMap<String, FundDaily>();

	@SuppressWarnings({ "unchecked" })
	public void run() {
		logger.debug(Calendar.getInstance());
		// 1.判断是否交易日
		if (StockUtil.isNotDayTrading()) {
			logger.info("date: " + new Date() + " is not day trading ");
			return;
		}

		// 2.获取数据,解析数据,保存到DB
		this.getAndSaveData();

		// 3.更新fund-list.js
		this.updateFundListFile();

		// 4.发送SMS
		FetionHelper.sendMsg(this.createMsgList());

		// 5.清空MAP
		this.fundDailyMap.clear();
	}

	/**
	 * 获取数据,解析数据,保存到DB及内存
	 */
	public void getAndSaveData() {
		/**
		 * http://stock.finance.qq.com/fund/jzzx/kfs.js
		 */
		String[] styles = { "kfs.js", "fbs.js" };
		HttpClient client = StockUtil.getHttpClient();
		for (int i = 0; i < styles.length; i++) {
			String uri = "http://stock.finance.qq.com/fund/jzzx/";
			uri += styles[i];
			BufferedReader reader = null;
			GetMethod method = new GetMethod(uri);
			try {
				int returnCode = client.executeMethod(method);
				if (returnCode == HttpStatus.SC_NOT_IMPLEMENTED) {
					logger.error("The get method is not implemented by this URI");
					method.getResponseBodyAsString();
				} else {
					reader = new BufferedReader(new InputStreamReader(
							method.getResponseBodyAsStream(), "gb2312"));
					String readLine;
					String text = "";
					while (((readLine = reader.readLine()) != null)) {
						text += readLine;
					}
					// 解析并保存返回数据
					this.parseText(text);// 解析基金净值
					this.persistence.saveObjs(this.fundDailyMap.values()
							.toArray());// 保存基金净值
				}
			} catch (Exception e) {
				logger.error(e);
			} finally {
				method.releaseConnection();
				if (reader != null)
					try {
						reader.close();
					} catch (Exception fe) {
						logger.error(fe);
					}
			}
		}
	}

	/**
	 * 将返回的字符串转换成相应的对象
	 * 
	 * @throws ParseException
	 */
	public void parseText(String text) throws ParseException {
		/**
		 * 代码 简称 单位净值(元) 涨跌(元) 增长率(%) 累计净值(元) 净值日期 市场价格(元) 折价率(%)↓ 基金经理
		 * [["184690","基金同益","1.0513","-0.0125","-1.1750","4.3653","2011-07-22","0.932","-11.3479","王克玉","sz"],
		 * ["184690","基金同益","1.0513","-0.0125","-1.1750","4.3653","2011-07-22","0.932","-11.3479","王克玉","sz"]]
		 */

		String str = text.substring(text.indexOf("[[") + 2,
				text.lastIndexOf("]]")).replaceAll("\"", "");
		logger.debug(str);
		String[] funds = str.split("\\],\\[");
		String[] datas = null;
		FundDaily bo = null;
		Date date = new Date();
		for (int i = 0; i < funds.length; i++) {
			datas = funds[i].split(",");
			bo = new FundDaily();
			int j = 0;
			bo.setCode(datas[j++]);
			bo.setName(datas[j++]);
			bo.setUnitNetWorth(new Double(datas[j++]));
			bo.setChangeValue(new Double(datas[j++]));
			bo.setGrewRate(new Double(datas[j++]));
			bo.setAcmltNetValue(new Double(datas[j++]));
			bo.setNetValueDate(datas[j++]);
//			bo.setPrice()
//			bo.setDiscountRate();
			j++;j++;
			bo.setFundManager(datas[j++]);
			bo.setAchieveDate(date);
			this.fundDailyMap.put(bo.getCode(), bo);// 保存当前基金净值数据,用于发送SMS
		}
		logger.info("基金数" + fundDailyMap.size());
	}

	/**
	 * query subscript data ,create content
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List createMsgList() {
		List result = new ArrayList();
		String sql = " SELECT a.mobile_no,b.codes"
				+ "	 FROM (SELECT user_id,GROUP_CONCAT(fund_code) AS codes  "
				+ "			FROM fund_subscript GROUP BY user_id) AS b,"
				+ " user AS a" + " WHERE a.id = b.user_id"
				+ " AND a.mobile_no IS NOT NULL";
		logger.debug(sql);
		List<Object[]> list = this.persistence.queryBySql(sql);
		String fetionNo = null;
		String content = null;
		for (int i = 0; i < list.size(); i++) {
			try {
				fetionNo = list.get(i)[0].toString();
				content = getContent(list.get(i)[1].toString().split(","));
				result.add(new String[] { fetionNo, content.replace(" ","") });
			} catch (Exception e) {
				logger.error(e);
			}
		
		}
		return result;
	}

	/**
	 * 参数是分组合并后的对象
	 * 
	 * @param symbols
	 *            "600000,600001"
	 * @return
	 */
	public String getContent(String[] codes) {
		String content = "";
		for (String code : codes) {
			content += this.getText(code);
		}
		return content;
	}

	/**
	 * 根据STOCK编号组织信息内容
	 * 
	 * @param symbole
	 *            stock 编码
	 * @return
	 */
	public String getText(String code) {
		FundDaily fundDaily = this.fundDailyMap.get(code);
		Assert.notNull(fundDaily,"基金编号:"+ code + "不存在");
		String text = "";
		text += fundDaily.getName() + "(" + fundDaily.getCode() + ") ";
		text += "单位净值:" + fundDaily.getUnitNetWorth() + ",";
		text += "涨跌(元):"+fundDaily.getChangeValue()+ ",";
		text += "增长率:" + fundDaily.getGrewRate() + ",";
		text += "净值日期:" + fundDaily.getNetValueDate() + ".";
		return text;
	}

	public void updateFundListFile() {
		// STOCK_LIST = ["AAA(600590)", "BBB(500001)"];
		String dir = FileUtil.getRootDir() + Constants.JS_PATH
				+ Constants.FUND_LIST_NAME;
		logger.info(dir);
		// 1.delete old file
		File file = new File(dir);
		file.deleteOnExit();
		
		//2.create new file
		Writer writer = null;
		try {
			file.createNewFile();
			writer = new OutputStreamWriter(new FileOutputStream(file),
					Constants.CHAR_SET);
			writer.append("var FUND_LIST = [");
			writer.append(this.getArrayText());
			writer.append("];");
			writer.flush();
		} catch (IOException e) {
			logger.error(e);
		} finally {
			if (writer != null)
				try {
					writer.close();
				} catch (IOException e) {
					logger.error(e);
				}
		}
		logger.info("create fund-list.js: " + dir);

	}

	public String getArrayText() {
		String text = "";
		Iterator<FundDaily> iterator = this.fundDailyMap.values().iterator();
		FundDaily bo = null;
		while (iterator.hasNext()) {
			bo = iterator.next();
			text += "'" + bo.getName() + "(" + bo.getCode() + ")',";
		}
		return text;
	}

	public static void main(String[] args) {
		FundTask task = new FundTask();
		task.run();
//		String s = "\"19601\",\"海富通中国海外股票(QDII)\",\"1.5250\",\"0.0290\",\"1.9385\",\"1.7950\",\"2011-07-22\",\"开放\",\"开放\",\"杨铭\"],[\"110005\",\"易方达积极成长混合\",\"0.9310\",\"-0.0279\",\"-2.9096\",\"4.2209\",\"2011-07-25\",\"开放\",\"开放\",\"何云峰\"";
//		String[] funds = s.split("\\],\\[");
//		System.out.println(funds[0]);
//		System.out.println(funds[1]);
	}
}
